﻿using System;
using System.IO;
using System.Runtime.InteropServices;
using System.Text;
using ZK.Common;

namespace ZK.Camera
{
    public class Camera
    {
        private Int32[] m_lAlarmHandle = new Int32[200];
        private Int32 iListenHandle = -1;
        private int iDeviceNumber = 0; //添加设备个数
        private CameraSdk.MSGCallBack m_falarmData = null;
        public delegate void UpdateListBoxCallback(string strAlarmTime, string strDevIP, string strAlarmMsg);

        CameraSdk.NET_VCA_TRAVERSE_PLANE m_struTraversePlane = new CameraSdk.NET_VCA_TRAVERSE_PLANE();
        CameraSdk.NET_VCA_AREA m_struVcaArea = new CameraSdk.NET_VCA_AREA();
        CameraSdk.NET_VCA_INTRUSION m_struIntrusion = new CameraSdk.NET_VCA_INTRUSION();
        CameraSdk.UNION_STATFRAME m_struStatFrame = new CameraSdk.UNION_STATFRAME();
        CameraSdk.UNION_STATTIME m_struStatTime = new CameraSdk.UNION_STATTIME();
        private readonly int _mUserId;

        public Action<DateTime, string, string> ReceiveAlarm;

        public Action<string, string, string, int> GrabTheLicensePlateNumber;

        public bool IsLogin = false;

        public int UserId { get; set; }

        public Camera(CameraSetup setup)
        {
            bool m_bInitSDK = CameraSdk.NET_DVR_Init();
            if (m_bInitSDK == false)
            {
                Common.Log4.LogManage.WriteErr(@"NET_DVR_Init error!");
                return;
            }
            else
            {
                byte[] strIP = new byte[16 * 16];
                if (setup.CameraType == 1)
                {
                    //保存SDK日志 To save the SDK log
                    CameraSdk.NET_DVR_SetLogToFile(3, "C:\\SdkLog\\", true);
                    for (int i = 0; i < 200; i++)
                    {
                        m_lAlarmHandle[i] = -1;
                    }

                    //设置报警回调函数
                    m_falarmData = new CameraSdk.MSGCallBack(MsgCallback);
                    CameraSdk.NET_DVR_SetDVRMessageCallBack_V30(m_falarmData, IntPtr.Zero);
                }
            }

            if (AutoLogin(setup.CameraIp, setup.CameraPort, setup.UserName, setup.Password, out _mUserId))
            {
                UserId = _mUserId;
                if (setup.CameraType == 1)
                {
                    if (SetAlarm(_mUserId))
                    {
                        StartListen(setup.LocalIp, setup.LocalPort);
                    }
                }
                else if (setup.CameraType == 2)
                {
                    IsLogin = true;
                }
            }
        }

        //public Camera(List<CameraSetup> setup)
        //{
        //    bool m_bInitSDK = CameraSdk.NET_DVR_Init();
        //    if (m_bInitSDK == false)
        //    {
        //        Common.Log4.LogManage.WriteErr(@"NET_DVR_Init error!");
        //    }
        //    else
        //    {
        //        if (setup[0].CameraType == 1)
        //        {
        //            //保存SDK日志 To save the SDK log
        //            CameraSdk.NET_DVR_SetLogToFile(3, "C:\\SdkLog\\", true);
        //            for (int i = 0; i < 200; i++)
        //            {
        //                m_lAlarmHandle[i] = -1;
        //            }

        //            //设置报警回调函数
        //            m_falarmData = new CameraSdk.MSGCallBack(MsgCallback);
        //            CameraSdk.NET_DVR_SetDVRMessageCallBack_V30(m_falarmData, IntPtr.Zero);
        //        }
        //    }

        //    foreach (var item in setup)
        //    {
        //        if (AutoLogin(item.CameraIp, item.CameraPort, item.UserName, item.Password, out _mUserId))
        //        {
        //            UserId = _mUserId;
        //            if (item.CameraType == 1)
        //            {
        //                if (SetAlarm(_mUserId))
        //                {
        //                    StartListen(item.LocalIp, item.LocalPort);
        //                }
        //            }
        //            else if (item.CameraType == 2)
        //            {
        //                IsLogin = true;
        //                UserId = _mUserId;
        //            }
        //        }
        //    }
        //}

        /// <summary>
        /// 抓拍图片
        /// </summary>
        /// <returns></returns>
        public string GetDVRPic()
        {
            string strPicPath = string.Empty;
            if (UserId >= 0)
            {
                ////DVR工作状态
                //IntPtr pWorkState = new IntPtr();
                //if (!CameraSdk.NET_DVR_GetDVRWorkState_V30(UserId, pWorkState))
                //{
                //    // 返回Boolean值，判断是否获取设备能力
                //    Common.Log4.LogManage.WriteInfo(@"返回设备状态失败");
                //}

                CameraSdk.NET_DVR_JPEGPARA lpJpegPara = new CameraSdk.NET_DVR_JPEGPARA();
                lpJpegPara.wPicQuality = 2; //图像质量 Image quality
                lpJpegPara.wPicSize = 0xff; //抓图分辨率 Picture size: 2- 4CIF，0xff- Auto(使用当前码流分辨率)，抓图分辨率需要设备支持，更多取值请参考SDK文档

                //JEPG抓图，数据保存在缓冲区中 Capture a JPEG picture and save in the buffer
                uint iBuffSize = 400000; //缓冲区大小需要不小于一张图片数据的大小 The buffer size should not be less than the picture size
                byte[] byJpegPicBuffer = new byte[iBuffSize];
                uint dwSizeReturned = 0;

                if (!CameraSdk.NET_DVR_CaptureJPEGPicture_NEW(UserId, 1, ref lpJpegPara, byJpegPicBuffer, iBuffSize, ref dwSizeReturned))
                {
                    uint iLastErr = CameraSdk.NET_DVR_GetLastError();
                    Common.Log4.LogManage.WriteErr("NET_DVR_CaptureJPEGPicture_NEW failed, error code= " + iLastErr);
                }
                else
                {
                    //将缓冲区里的JPEG图片数据写入文件 save the data into a file
                    var saveDirectory = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "GrabbedImages", DateTime.Now.ToString("yyyyMMdd"));
                    string fileName = "CapturePicture_" + DateTime.Now.ToString("yyyyMMddHHmmssfff") + ".jpg";
                    if (!Directory.Exists(saveDirectory))
                        Directory.CreateDirectory(saveDirectory);
                    var path = Path.Combine(saveDirectory, fileName);
                    FileStream fs = new FileStream(path, FileMode.Create);
                    int iLen = (int)dwSizeReturned;
                    fs.Write(byJpegPicBuffer, 0, iLen);
                    fs.Close();
                    strPicPath = path;
                }
            }
            return strPicPath;
        }

        public bool MsgCallback_V31(int lCommand, ref CameraSdk.NET_DVR_ALARMER pAlarmer, IntPtr pAlarmInfo,
            uint dwBufLen, IntPtr pUser)
        {
            //通过lCommand来判断接收到的报警信息类型，不同的lCommand对应不同的pAlarmInfo内容
            AlarmMessageHandle(lCommand, ref pAlarmer, pAlarmInfo, dwBufLen, pUser);

            return true; //回调函数需要有返回，表示正常接收到数据
        }

        public void MsgCallback(int lCommand, ref CameraSdk.NET_DVR_ALARMER pAlarmer, IntPtr pAlarmInfo, uint dwBufLen, IntPtr pUser)
        {
            //通过lCommand来判断接收到的报警信息类型，不同的lCommand对应不同的pAlarmInfo内容
            AlarmMessageHandle(lCommand, ref pAlarmer, pAlarmInfo, dwBufLen, pUser);
        }

        /// <summary>
        /// 道闸控制
        /// </summary>
        /// <param name="cmdFlag">
        /// 代码：1 开启道闸 0 关闭道闸 2停止道闸  3 锁定道闸
        /// </param>
        public bool BarrierGateControl(byte cmdFlag)
        {
            try
            {
                CameraSdk.NET_DVR_BARRIERGATE_CFG mStruControlCond = new CameraSdk.NET_DVR_BARRIERGATE_CFG();
                Int32 dwSize = Marshal.SizeOf(mStruControlCond);
                mStruControlCond.dwSize = (uint)dwSize;
                mStruControlCond.dwChannel = 1;
                mStruControlCond.byLaneNo = 1;
                mStruControlCond.byBarrierGateCtrl = cmdFlag;

                IntPtr ptrControlCfg = Marshal.AllocHGlobal(dwSize);
                Marshal.StructureToPtr(mStruControlCond, ptrControlCfg, false);

                if (!CameraSdk.NET_DVR_RemoteControl(UserId, CameraSdk.NET_DVR_BARRIERGATE_CTRL, ptrControlCfg, (UInt32)dwSize))
                {
                    uint iLastErr = CameraSdk.NET_DVR_GetLastError();
                    Common.Log4.LogManage.WriteErr("NET_DVR_BARRIERGATE_CTRL failed, error code= " + iLastErr);
                    return false;
                }
                Marshal.FreeHGlobal(ptrControlCfg);
            }
            catch (Exception ex)
            {
                Common.Log4.LogManage.WriteErr(ex.ToString());
                return false;
            }
            return true;
        }

        public void AlarmMessageHandle(int lCommand, ref CameraSdk.NET_DVR_ALARMER pAlarmer, IntPtr pAlarmInfo,
            uint dwBufLen, IntPtr pUser)
        {
            //通过lCommand来判断接收到的报警信息类型，不同的lCommand对应不同的pAlarmInfo内容
            switch (lCommand)
            {
                case CameraSdk.COMM_ALARM: //(DS-8000老设备)移动侦测、视频丢失、遮挡、IO信号量等报警信息
                    ProcessCommAlarm(ref pAlarmer, pAlarmInfo, dwBufLen, pUser);
                    break;
                case CameraSdk.COMM_ALARM_V30: //移动侦测、视频丢失、遮挡、IO信号量等报警信息
                    ProcessCommAlarm_V30(ref pAlarmer, pAlarmInfo, dwBufLen, pUser);
                    break;
                case CameraSdk.COMM_ALARM_RULE: //进出区域、入侵、徘徊、人员聚集等行为分析报警信息
                    ProcessCommAlarm_RULE(ref pAlarmer, pAlarmInfo, dwBufLen, pUser);
                    break;
                case CameraSdk.COMM_UPLOAD_PLATE_RESULT: //交通抓拍结果上传(老报警信息类型)
                    ProcessCommAlarm_Plate(ref pAlarmer, pAlarmInfo, dwBufLen, pUser);
                    break;
                case CameraSdk.COMM_ITS_PLATE_RESULT: //交通抓拍结果上传(新报警信息类型)
                    ProcessCommAlarm_ITSPlate(ref pAlarmer, pAlarmInfo, dwBufLen, pUser);
                    break;
                case CameraSdk.COMM_ALARM_PDC: //客流量统计报警信息
                    ProcessCommAlarm_PDC(ref pAlarmer, pAlarmInfo, dwBufLen, pUser);
                    break;
                case CameraSdk.COMM_ITS_PARK_VEHICLE: //客流量统计报警信息
                    ProcessCommAlarm_PARK(ref pAlarmer, pAlarmInfo, dwBufLen, pUser);
                    break;
                case CameraSdk.COMM_DIAGNOSIS_UPLOAD: //VQD报警信息
                    ProcessCommAlarm_VQD(ref pAlarmer, pAlarmInfo, dwBufLen, pUser);
                    break;
                case CameraSdk.COMM_UPLOAD_FACESNAP_RESULT: //人脸抓拍结果信息
                    ProcessCommAlarm_FaceSnap(ref pAlarmer, pAlarmInfo, dwBufLen, pUser);
                    break;
                case CameraSdk.COMM_SNAP_MATCH_ALARM: //人脸比对结果信息
                    ProcessCommAlarm_FaceMatch(ref pAlarmer, pAlarmInfo, dwBufLen, pUser);
                    break;
                case CameraSdk.COMM_ALARMHOST_CID_ALARM: //报警主机CID报警上传
                    ProcessCommAlarm_CIDAlarm(ref pAlarmer, pAlarmInfo, dwBufLen, pUser);
                    break;
                default:
                    {
                        //报警设备IP地址
                        var strIp = pAlarmer.sDeviceIP;

                        //报警信息类型
                        var stringAlarm = "报警上传，信息类型：" + lCommand;

                        ReceiveAlarm?.Invoke(DateTime.Now, strIp, stringAlarm);
                    }
                    break;
            }
        }

        public void ProcessCommAlarm(ref CameraSdk.NET_DVR_ALARMER pAlarmer, IntPtr pAlarmInfo, uint dwBufLen,
            IntPtr pUser)
        {
            var struAlarmInfo =
                (CameraSdk.NET_DVR_ALARMINFO)Marshal.PtrToStructure(pAlarmInfo, typeof(CameraSdk.NET_DVR_ALARMINFO));

            var strIp = pAlarmer.sDeviceIP;
            var stringAlarm = "";
            var i = 0;

            switch (struAlarmInfo.dwAlarmType)
            {
                case 0:
                    stringAlarm = "信号量报警，报警报警输入口：" + struAlarmInfo.dwAlarmInputNumber + "，触发录像通道：";
                    for (i = 0; i < CameraSdk.MAX_CHANNUM; i++)
                        if (struAlarmInfo.dwAlarmRelateChannel[i] == 1)
                            stringAlarm += i + 1 + " \\ ";
                    break;
                case 1:
                    stringAlarm = "硬盘满，报警硬盘号：";
                    for (i = 0; i < CameraSdk.MAX_DISKNUM; i++)
                        if (struAlarmInfo.dwDiskNumber[i] == 1)
                            stringAlarm += i + 1 + " \\ ";
                    break;
                case 2:
                    stringAlarm = "信号丢失，报警通道：";
                    for (i = 0; i < CameraSdk.MAX_CHANNUM; i++)
                        if (struAlarmInfo.dwChannel[i] == 1)
                            stringAlarm += i + 1 + " \\ ";
                    break;
                case 3:
                    stringAlarm = "移动侦测，报警通道：";
                    for (i = 0; i < CameraSdk.MAX_CHANNUM; i++)
                        if (struAlarmInfo.dwChannel[i] == 1)
                            stringAlarm += i + 1 + " \\ ";
                    break;
                case 4:
                    stringAlarm = "硬盘未格式化，报警硬盘号：";
                    for (i = 0; i < CameraSdk.MAX_DISKNUM; i++)
                        if (struAlarmInfo.dwDiskNumber[i] == 1)
                            stringAlarm += i + 1 + " \\ ";
                    break;
                case 5:
                    stringAlarm = "读写硬盘出错，报警硬盘号：";
                    for (i = 0; i < CameraSdk.MAX_DISKNUM; i++)
                        if (struAlarmInfo.dwDiskNumber[i] == 1)
                            stringAlarm += i + 1 + " \\ ";
                    break;
                case 6:
                    stringAlarm = "遮挡报警，报警通道：";
                    for (i = 0; i < CameraSdk.MAX_CHANNUM; i++)
                        if (struAlarmInfo.dwChannel[i] == 1)
                            stringAlarm += i + 1 + " \\ ";
                    break;
                case 7:
                    stringAlarm = "制式不匹配，报警通道";
                    for (i = 0; i < CameraSdk.MAX_CHANNUM; i++)
                        if (struAlarmInfo.dwChannel[i] == 1)
                            stringAlarm += i + 1 + " \\ ";
                    break;
                case 8:
                    stringAlarm = "非法访问";
                    break;
                default:
                    stringAlarm = "其他未知报警信息";
                    break;
            }

            ReceiveAlarm?.Invoke(DateTime.Now, strIp, stringAlarm);
        }

        private void ProcessCommAlarm_V30(ref CameraSdk.NET_DVR_ALARMER pAlarmer, IntPtr pAlarmInfo, uint dwBufLen,
            IntPtr pUser)
        {
            var struAlarmInfoV30 =
                (CameraSdk.NET_DVR_ALARMINFO_V30)Marshal.PtrToStructure(pAlarmInfo,
                    typeof(CameraSdk.NET_DVR_ALARMINFO_V30));

            var strIp = pAlarmer.sDeviceIP;
            var stringAlarm = "";
            int i;

            switch (struAlarmInfoV30.dwAlarmType)
            {
                case 0:
                    stringAlarm = "信号量报警，报警报警输入口：" + struAlarmInfoV30.dwAlarmInputNumber + "，触发录像通道：";
                    for (i = 0; i < CameraSdk.MAX_CHANNUM_V30; i++)
                        if (struAlarmInfoV30.byAlarmRelateChannel[i] == 1)
                            stringAlarm += i + 1 + "\\";
                    break;
                case 1:
                    stringAlarm = "硬盘满，报警硬盘号：";
                    for (i = 0; i < CameraSdk.MAX_DISKNUM_V30; i++)
                        if (struAlarmInfoV30.byDiskNumber[i] == 1)
                            stringAlarm += i + 1 + " ";
                    break;
                case 2:
                    stringAlarm = "信号丢失，报警通道：";
                    for (i = 0; i < CameraSdk.MAX_CHANNUM_V30; i++)
                        if (struAlarmInfoV30.byChannel[i] == 1)
                            stringAlarm += i + 1 + " \\ ";
                    break;
                case 3:
                    stringAlarm = "移动侦测，报警通道：";
                    for (i = 0; i < CameraSdk.MAX_CHANNUM_V30; i++)
                        if (struAlarmInfoV30.byChannel[i] == 1)
                            stringAlarm += i + 1 + " \\ ";
                    break;
                case 4:
                    stringAlarm = "硬盘未格式化，报警硬盘号：";
                    for (i = 0; i < CameraSdk.MAX_DISKNUM_V30; i++)
                        if (struAlarmInfoV30.byDiskNumber[i] == 1)
                            stringAlarm += i + 1 + " \\ ";
                    break;
                case 5:
                    stringAlarm = "读写硬盘出错，报警硬盘号：";
                    for (i = 0; i < CameraSdk.MAX_DISKNUM_V30; i++)
                        if (struAlarmInfoV30.byDiskNumber[i] == 1)
                            stringAlarm += i + 1 + " \\ ";
                    break;
                case 6:
                    stringAlarm = "遮挡报警，报警通道：";
                    for (i = 0; i < CameraSdk.MAX_CHANNUM_V30; i++)
                        if (struAlarmInfoV30.byChannel[i] == 1)
                            stringAlarm += i + 1 + " \\ ";
                    break;
                case 7:
                    stringAlarm = "制式不匹配，报警通道";
                    for (i = 0; i < CameraSdk.MAX_CHANNUM_V30; i++)
                        if (struAlarmInfoV30.byChannel[i] == 1)
                            stringAlarm += i + 1 + " \\ ";
                    break;
                case 8:
                    stringAlarm = "非法访问";
                    break;
                case 9:
                    stringAlarm = "视频信号异常，报警通道";
                    for (i = 0; i < CameraSdk.MAX_CHANNUM_V30; i++)
                        if (struAlarmInfoV30.byChannel[i] == 1)
                            stringAlarm += i + 1 + " \\ ";
                    break;
                case 10:
                    stringAlarm = "录像/抓图异常，报警通道";
                    for (i = 0; i < CameraSdk.MAX_CHANNUM_V30; i++)
                        if (struAlarmInfoV30.byChannel[i] == 1)
                            stringAlarm += i + 1 + " \\ ";
                    break;
                case 11:
                    stringAlarm = "智能场景变化，报警通道";
                    for (i = 0; i < CameraSdk.MAX_CHANNUM_V30; i++)
                        if (struAlarmInfoV30.byChannel[i] == 1)
                            stringAlarm += i + 1 + " \\ ";
                    break;
                case 12:
                    stringAlarm = "阵列异常";
                    break;
                case 13:
                    stringAlarm = "前端/录像分辨率不匹配，报警通道";
                    for (i = 0; i < CameraSdk.MAX_CHANNUM_V30; i++)
                        if (struAlarmInfoV30.byChannel[i] == 1)
                            stringAlarm += i + 1 + " \\ ";
                    break;
                case 15:
                    stringAlarm = "智能侦测，报警通道";
                    for (i = 0; i < CameraSdk.MAX_CHANNUM_V30; i++)
                        if (struAlarmInfoV30.byChannel[i] == 1)
                            stringAlarm += i + 1 + " \\ ";
                    break;
                default:
                    stringAlarm = "其他未知报警信息";
                    break;
            }

            ReceiveAlarm?.Invoke(DateTime.Now, strIp, stringAlarm);
        }

        private void ProcessCommAlarm_RULE(ref CameraSdk.NET_DVR_ALARMER pAlarmer, IntPtr pAlarmInfo, uint dwBufLen,
            IntPtr pUser)
        {
            var struRuleAlarmInfo = (CameraSdk.NET_VCA_RULE_ALARM)Marshal.PtrToStructure(pAlarmInfo, typeof(CameraSdk.NET_VCA_RULE_ALARM));

            //报警信息
            var stringAlarm = "";
            var dwSize = (uint)Marshal.SizeOf(struRuleAlarmInfo.struRuleInfo.uEventParam);

            switch (struRuleAlarmInfo.struRuleInfo.wEventTypeEx)
            {
                case (ushort)CameraSdk.VCA_RULE_EVENT_TYPE_EX.ENUM_VCA_EVENT_TRAVERSE_PLANE:
                    var ptrTraverseInfo = Marshal.AllocHGlobal((int)dwSize);
                    Marshal.StructureToPtr(struRuleAlarmInfo.struRuleInfo.uEventParam, ptrTraverseInfo, false);
                    m_struTraversePlane =
                        (CameraSdk.NET_VCA_TRAVERSE_PLANE)Marshal.PtrToStructure(ptrTraverseInfo,
                            typeof(CameraSdk.NET_VCA_TRAVERSE_PLANE));
                    stringAlarm = "穿越警戒面，目标ID：" + struRuleAlarmInfo.struTargetInfo.dwID;
                    //警戒面边线起点坐标: (m_struTraversePlane.struPlaneBottom.struStart.fX, m_struTraversePlane.struPlaneBottom.struStart.fY)
                    //警戒面边线终点坐标: (m_struTraversePlane.struPlaneBottom.struEnd.fX, m_struTraversePlane.struPlaneBottom.struEnd.fY)
                    break;
                case (ushort)CameraSdk.VCA_RULE_EVENT_TYPE_EX.ENUM_VCA_EVENT_ENTER_AREA:
                    var ptrEnterInfo = Marshal.AllocHGlobal((int)dwSize);
                    Marshal.StructureToPtr(struRuleAlarmInfo.struRuleInfo.uEventParam, ptrEnterInfo, false);
                    m_struVcaArea =
                        (CameraSdk.NET_VCA_AREA)Marshal.PtrToStructure(ptrEnterInfo, typeof(CameraSdk.NET_VCA_AREA));
                    stringAlarm = "目标进入区域，目标ID：" + struRuleAlarmInfo.struTargetInfo.dwID;
                    //m_struVcaArea.struRegion 多边形区域坐标
                    break;
                case (ushort)CameraSdk.VCA_RULE_EVENT_TYPE_EX.ENUM_VCA_EVENT_EXIT_AREA:
                    var ptrExitInfo = Marshal.AllocHGlobal((int)dwSize);
                    Marshal.StructureToPtr(struRuleAlarmInfo.struRuleInfo.uEventParam, ptrExitInfo, false);
                    m_struVcaArea =
                        (CameraSdk.NET_VCA_AREA)Marshal.PtrToStructure(ptrExitInfo, typeof(CameraSdk.NET_VCA_AREA));
                    stringAlarm = "目标离开区域，目标ID：" + struRuleAlarmInfo.struTargetInfo.dwID;
                    //m_struVcaArea.struRegion 多边形区域坐标
                    break;
                case (ushort)CameraSdk.VCA_RULE_EVENT_TYPE_EX.ENUM_VCA_EVENT_INTRUSION:
                    var ptrIntrusionInfo = Marshal.AllocHGlobal((int)dwSize);
                    Marshal.StructureToPtr(struRuleAlarmInfo.struRuleInfo.uEventParam, ptrIntrusionInfo, false);
                    m_struIntrusion =
                        (CameraSdk.NET_VCA_INTRUSION)Marshal.PtrToStructure(ptrIntrusionInfo,
                            typeof(CameraSdk.NET_VCA_INTRUSION));

                    var i = 0;
                    var strRegion = "";
                    for (i = 0; i < m_struIntrusion.struRegion.dwPointNum; i++)
                        strRegion = strRegion + "(" + m_struIntrusion.struRegion.struPos[i].fX + "," +
                                    m_struIntrusion.struRegion.struPos[i].fY + ")";
                    stringAlarm = "周界入侵，目标ID：" + struRuleAlarmInfo.struTargetInfo.dwID + "，区域范围：" + strRegion;
                    //m_struIntrusion.struRegion 多边形区域坐标
                    break;
                default:
                    stringAlarm = "其他行为分析报警，目标ID：" + struRuleAlarmInfo.struTargetInfo.dwID;
                    break;
            }


            //报警图片保存
            if (struRuleAlarmInfo.dwPicDataLen > 0)
            {
                var fs = new FileStream("行为分析报警抓图.jpg", FileMode.Create);
                var iLen = (int)struRuleAlarmInfo.dwPicDataLen;
                var by = new byte[iLen];
                Marshal.Copy(struRuleAlarmInfo.pImage, by, 0, iLen);
                fs.Write(by, 0, iLen);
                fs.Close();
            }

            //报警时间：年月日时分秒
            var strTimeYear = ((struRuleAlarmInfo.dwAbsTime >> 26) + 2000).ToString();
            var strTimeMonth = ((struRuleAlarmInfo.dwAbsTime >> 22) & 15).ToString("d2");
            var strTimeDay = ((struRuleAlarmInfo.dwAbsTime >> 17) & 31).ToString("d2");
            var strTimeHour = ((struRuleAlarmInfo.dwAbsTime >> 12) & 31).ToString("d2");
            var strTimeMinute = ((struRuleAlarmInfo.dwAbsTime >> 6) & 63).ToString("d2");
            var strTimeSecond = ((struRuleAlarmInfo.dwAbsTime >> 0) & 63).ToString("d2");
            var strTime = strTimeYear + "-" + strTimeMonth + "-" + strTimeDay + " " + strTimeHour + ":" +
                          strTimeMinute + ":" + strTimeSecond;

            //报警设备IP地址
            var strIp = struRuleAlarmInfo.struDevInfo.struDevIP.sIpV4;

            ReceiveAlarm?.Invoke(DateTime.Now, strIp, stringAlarm);
        }

        private void ProcessCommAlarm_Plate(ref CameraSdk.NET_DVR_ALARMER pAlarmer, IntPtr pAlarmInfo, uint dwBufLen,
            IntPtr pUser)
        {
            var struPlateResultInfo =
                (CameraSdk.NET_DVR_PLATE_RESULT)Marshal.PtrToStructure(pAlarmInfo,
                    typeof(CameraSdk.NET_DVR_PLATE_RESULT));

            //保存抓拍图片
            var str = "";
            if (struPlateResultInfo.byResultType == 1 && struPlateResultInfo.dwPicLen != 0)
            {
                str = "Plate_UserID_" + pAlarmer.lUserID + "_近景图.jpg";
                var fs = new FileStream(str, FileMode.Create);
                var iLen = (int)struPlateResultInfo.dwPicLen;
                var by = new byte[iLen];
                Marshal.Copy(struPlateResultInfo.pBuffer1, by, 0, iLen);
                fs.Write(by, 0, iLen);
                fs.Close();
            }
            if (struPlateResultInfo.dwPicPlateLen != 0)
            {
                str = "Plate_UserID_" + pAlarmer.lUserID + "_车牌图.jpg";
                var fs = new FileStream(str, FileMode.Create);
                var iLen = (int)struPlateResultInfo.dwPicPlateLen;
                var by = new byte[iLen];
                Marshal.Copy(struPlateResultInfo.pBuffer2, by, 0, iLen);
                fs.Write(by, 0, iLen);
                fs.Close();
            }
            if (struPlateResultInfo.dwFarCarPicLen != 0)
            {
                str = "Plate_UserID_" + pAlarmer.lUserID + "_远景图.jpg";
                var fs = new FileStream(str, FileMode.Create);
                var iLen = (int)struPlateResultInfo.dwFarCarPicLen;
                var by = new byte[iLen];
                Marshal.Copy(struPlateResultInfo.pBuffer5, by, 0, iLen);
                fs.Write(by, 0, iLen);
                fs.Close();
            }

            //报警设备IP地址
            var strIp = pAlarmer.sDeviceIP;

            //抓拍时间：年月日时分秒
            var strTimeYear = Encoding.UTF8.GetString(struPlateResultInfo.byAbsTime);

            //上传结果
            //var stringPlateLicense = Encoding.GetEncoding("GBK").GetString(struPlateResultInfo.struPlateInfo.sLicense)
            //    .TrimEnd('\0');

            string stringAlarm = "抓拍上传，" + "车牌：" + struPlateResultInfo.struPlateInfo.sLicense + "，车辆序号：" + struPlateResultInfo.struVehicleInfo.dwIndex;

            ReceiveAlarm?.Invoke(DateTime.Now, strIp, stringAlarm);
        }

        private void ProcessCommAlarm_ITSPlate(ref CameraSdk.NET_DVR_ALARMER pAlarmer, IntPtr pAlarmInfo, uint dwBufLen,
            IntPtr pUser)
        {
            var struItsPlateResult =
                (CameraSdk.NET_ITS_PLATE_RESULT)Marshal.PtrToStructure(pAlarmInfo,
                    typeof(CameraSdk.NET_ITS_PLATE_RESULT));

            //报警设备IP地址
            var strIp = pAlarmer.sDeviceIP;

            //抓拍时间：年月日时分秒
            var strTimeYear = $"{struItsPlateResult.struSnapFirstPicTime.wYear:D4}" +
                              $"{struItsPlateResult.struSnapFirstPicTime.byMonth:D2}" +
                              $"{struItsPlateResult.struSnapFirstPicTime.byDay:D2}" + " "
                              + $"{struItsPlateResult.struSnapFirstPicTime.byHour:D2}" + ":"
                              + $"{struItsPlateResult.struSnapFirstPicTime.byMinute:D2}" + ":"
                              + $"{struItsPlateResult.struSnapFirstPicTime.bySecond:D2}" + ":"
                              + $"{struItsPlateResult.struSnapFirstPicTime.wMilliSec:D3}";

            //上传结果
            var stringPlateLicense = Encoding.GetEncoding("GBK").GetString(struItsPlateResult.struPlateInfo.sLicense)
                .TrimEnd('\0');
            if (!string.IsNullOrEmpty(stringPlateLicense))
            {
                stringPlateLicense = stringPlateLicense.Substring(1);
            }
            var stringAlarm = "抓拍上传，" + "车牌：" + stringPlateLicense + "，车辆序号：" +
                              struItsPlateResult.struVehicleInfo.dwIndex;

            if (stringPlateLicense.Length < 7)
            {
                return;
            }
            Common.Log4.LogManage.WriteInfo("车牌识别一体机识别到的车牌为:" + stringPlateLicense);

            ReceiveAlarm?.Invoke(DateTime.Now, strIp, stringAlarm);

            //删除七天前的抓拍图片
            var baseDirectory = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "GrabbedImages");
            if (Directory.Exists(baseDirectory))
            {
                var directories = Directory.GetDirectories(baseDirectory);
                foreach (var item in directories)
                {
                    var info = new DirectoryInfo(item);
                    if (info.Exists && (info.Attributes & FileAttributes.Directory) != 0 &&
                        info.CreationTime < DateTime.Now.AddDays(-7))
                        Directory.Delete(item, true);
                }
            }

            //保存抓拍图片
            var strDate = $"{struItsPlateResult.struSnapFirstPicTime.wYear:D4}" +
                          $"{struItsPlateResult.struSnapFirstPicTime.byMonth:D2}" +
                          $"{struItsPlateResult.struSnapFirstPicTime.byDay:D2}";
            var strDateTime = $"{strDate}" +
                              $"{struItsPlateResult.struSnapFirstPicTime.byHour:D2}" +
                              $"{struItsPlateResult.struSnapFirstPicTime.byMinute:D2}" +
                              $"{struItsPlateResult.struSnapFirstPicTime.bySecond:D2}" +
                              $"{struItsPlateResult.struSnapFirstPicTime.wMilliSec:D3}";
            var grabbedImgPath = string.Empty;
            var carNumberImgPath = string.Empty;
            var caremaId = 0;
            for (var i = 0; i < struItsPlateResult.dwPicNum; i++)
                if (struItsPlateResult.struPicInfo[i].dwDataLen != 0)
                {
                    //var fileName = strDateTime + "_" + (string.IsNullOrEmpty(stringPlateLicense) ? "null" : stringPlateLicense) +
                    //        "_ITS_UserID_[" + pAlarmer.lUserID + "]_Pictype_" +
                    //        struItsPlateResult.struPicInfo[i].byType + "_Num" + (i + 1) + ".jpg";
                    caremaId = pAlarmer.lUserID;
                    var fileName = strDateTime + "_" + (string.IsNullOrEmpty(stringPlateLicense) ? "null" : stringPlateLicense) +
                            "_Pictype" + struItsPlateResult.struPicInfo[i].byType + "_Num" + (i + 1) + ".jpg";
                    var saveDirectory = Path.Combine(baseDirectory, strDate);
                    if (!Directory.Exists(saveDirectory))
                        Directory.CreateDirectory(saveDirectory);
                    var path = Path.Combine(saveDirectory, fileName);
                    var fs = new FileStream(path, FileMode.Create);
                    var iLen = (int)struItsPlateResult.struPicInfo[i].dwDataLen;
                    var by = new byte[iLen];
                    Marshal.Copy(struItsPlateResult.struPicInfo[i].pBuffer, by, 0, iLen);
                    fs.Write(by, 0, iLen);
                    fs.Close();
                    if (i == 0)
                        grabbedImgPath = path;
                    if (i == 1)
                        carNumberImgPath = path;
                }

            if (!string.IsNullOrEmpty(stringPlateLicense) && stringPlateLicense != "无车牌" && stringPlateLicense != "车牌")
                GrabTheLicensePlateNumber?.Invoke(stringPlateLicense, grabbedImgPath, carNumberImgPath, caremaId);



        }

        private void ProcessCommAlarm_PDC(ref CameraSdk.NET_DVR_ALARMER pAlarmer, IntPtr pAlarmInfo, uint dwBufLen,
            IntPtr pUser)
        {
            var struPdcInfo = new CameraSdk.NET_DVR_PDC_ALRAM_INFO();
            var dwSize = (uint)Marshal.SizeOf(struPdcInfo);
            struPdcInfo =
                (CameraSdk.NET_DVR_PDC_ALRAM_INFO)Marshal.PtrToStructure(pAlarmInfo,
                    typeof(CameraSdk.NET_DVR_PDC_ALRAM_INFO));

            var stringAlarm = "客流量统计，进入人数：" + struPdcInfo.dwEnterNum + "，离开人数：" + struPdcInfo.dwLeaveNum;

            var dwUnionSize = (uint)Marshal.SizeOf(struPdcInfo.uStatModeParam);
            var ptrPdcUnion = Marshal.AllocHGlobal((int)dwUnionSize);
            Marshal.StructureToPtr(struPdcInfo.uStatModeParam, ptrPdcUnion, false);

            if (struPdcInfo.byMode == 0) //单帧统计结果，此处为UTC时间
            {
                m_struStatFrame =
                    (CameraSdk.UNION_STATFRAME)Marshal.PtrToStructure(ptrPdcUnion, typeof(CameraSdk.UNION_STATFRAME));
                stringAlarm = stringAlarm + "，单帧统计，相对时标：" + m_struStatFrame.dwRelativeTime + "，绝对时标：" +
                              m_struStatFrame.dwAbsTime;
            }
            if (struPdcInfo.byMode == 1) //最小时间段统计结果
            {
                m_struStatTime =
                    (CameraSdk.UNION_STATTIME)Marshal.PtrToStructure(ptrPdcUnion, typeof(CameraSdk.UNION_STATTIME));

                //开始时间
                var strStartTime = $"{m_struStatTime.tmStart.dwYear:D4}" +
                                   $"{m_struStatTime.tmStart.dwMonth:D2}" +
                                   $"{m_struStatTime.tmStart.dwDay:D2}" + " "
                                   + $"{m_struStatTime.tmStart.dwHour:D2}" + ":"
                                   + $"{m_struStatTime.tmStart.dwMinute:D2}" + ":"
                                   + $"{m_struStatTime.tmStart.dwSecond:D2}";

                //结束时间
                var strEndTime = $"{m_struStatTime.tmEnd.dwYear:D4}" +
                                 $"{m_struStatTime.tmEnd.dwMonth:D2}" +
                                 $"{m_struStatTime.tmEnd.dwDay:D2}" + " "
                                 + $"{m_struStatTime.tmEnd.dwHour:D2}" + ":"
                                 + $"{m_struStatTime.tmEnd.dwMinute:D2}" + ":"
                                 + $"{m_struStatTime.tmEnd.dwSecond:D2}";

                stringAlarm = stringAlarm + "，最小时间段统计，开始时间：" + strStartTime + "，结束时间：" + strEndTime;
            }
            Marshal.FreeHGlobal(ptrPdcUnion);

            //报警设备IP地址
            var strIp = pAlarmer.sDeviceIP;

            ReceiveAlarm?.Invoke(DateTime.Now, strIp, stringAlarm);
        }

        private void ProcessCommAlarm_PARK(ref CameraSdk.NET_DVR_ALARMER pAlarmer, IntPtr pAlarmInfo, uint dwBufLen,
            IntPtr pUser)
        {
            //var struParkInfo = new CameraSdk.NET_ITS_PARK_VEHICLE();
            //var dwSize = (uint)Marshal.SizeOf(struParkInfo);
            //struParkInfo =
            //    (CameraSdk.NET_ITS_PARK_VEHICLE)Marshal.PtrToStructure(pAlarmInfo,
            //        typeof(CameraSdk.NET_ITS_PARK_VEHICLE));

            ////报警设备IP地址
            //var strIp = pAlarmer.sDeviceIP;

            ////保存抓拍图片
            //for (var i = 0; i < struParkInfo.dwPicNum; i++)
            //    if (struParkInfo.struPicInfo[i].dwDataLen != 0 && struParkInfo.struPicInfo[i].pBuffer != IntPtr.Zero)
            //    {
            //        var str = "Device_Park_[" + strIp + "]_lUerID_[" + pAlarmer.lUserID + "]_Pictype_" +
            //                  struParkInfo.struPicInfo[i].byType + "_Num" + (i + 1) + ".jpg";
            //        var fs = new FileStream(str, FileMode.Create);
            //        var iLen = (int)struParkInfo.struPicInfo[i].dwDataLen;
            //        var by = new byte[iLen];
            //        Marshal.Copy(struParkInfo.struPicInfo[i].pBuffer, by, 0, iLen);
            //        fs.Write(by, 0, iLen);
            //        fs.Close();
            //    }

            //var stringAlarm = "停车场数据上传，异常状态：" + struParkInfo.byParkError + "，车位编号：" + struParkInfo.byParkingNo +
            //                  ", 车辆状态：" + struParkInfo.byLocationStatus + "，车牌号码：" +
            //                  Encoding.GetEncoding("GBK").GetString(struParkInfo.struPlateInfo.sLicense).TrimEnd('\0');

            //ReceiveAlarm?.Invoke(DateTime.Now, strIp, stringAlarm);
        }

        private void ProcessCommAlarm_VQD(ref CameraSdk.NET_DVR_ALARMER pAlarmer, IntPtr pAlarmInfo, uint dwBufLen,
            IntPtr pUser)
        {
            //var struVqdInfo = new CameraSdk.NET_DVR_DIAGNOSIS_UPLOAD();
            //var dwSize = (uint)Marshal.SizeOf(struVqdInfo);
            //struVqdInfo =
            //    (CameraSdk.NET_DVR_DIAGNOSIS_UPLOAD)Marshal.PtrToStructure(pAlarmInfo,
            //        typeof(CameraSdk.NET_DVR_DIAGNOSIS_UPLOAD));

            ////报警设备IP地址
            //var strIp = pAlarmer.sDeviceIP;

            ////开始时间
            //var strCheckTime = $"{struVqdInfo.struCheckTime.dwYear:D4}" +
            //                   $"{struVqdInfo.struCheckTime.dwMonth:D2}" +
            //                   $"{struVqdInfo.struCheckTime.dwDay:D2}" + " "
            //                   + $"{struVqdInfo.struCheckTime.dwHour:D2}" + ":"
            //                   + $"{struVqdInfo.struCheckTime.dwMinute:D2}" + ":"
            //                   + $"{struVqdInfo.struCheckTime.dwSecond:D2}";

            //var stringAlarm = "视频质量诊断结果，流ID：" + struVqdInfo.sStreamID + "，监测点IP：" + struVqdInfo.sMonitorIP +
            //                  "，监控点通道号：" + struVqdInfo.dwChanIndex +
            //                  "，检测时间：" + strCheckTime + "，byResult：" + struVqdInfo.byResult + "，bySignalResult：" +
            //                  struVqdInfo.bySignalResult + "，byBlurResult：" + struVqdInfo.byBlurResult;

            //ReceiveAlarm?.Invoke(DateTime.Now, strIp, stringAlarm);
        }

        private void ProcessCommAlarm_FaceSnap(ref CameraSdk.NET_DVR_ALARMER pAlarmer, IntPtr pAlarmInfo, uint dwBufLen,
            IntPtr pUser)
        {
            var struFaceSnapInfo = new CameraSdk.NET_VCA_FACESNAP_RESULT();
            var dwSize = (uint)Marshal.SizeOf(struFaceSnapInfo);
            struFaceSnapInfo =
                (CameraSdk.NET_VCA_FACESNAP_RESULT)Marshal.PtrToStructure(pAlarmInfo,
                    typeof(CameraSdk.NET_VCA_FACESNAP_RESULT));

            //报警设备IP地址
            var strIp = pAlarmer.sDeviceIP;

            //保存抓拍图片数据
            if (struFaceSnapInfo.dwBackgroundPicLen != 0 && struFaceSnapInfo.pBuffer2 != IntPtr.Zero)
            {
                var str = "Device_FaceSnap_CapPic_[" + strIp + "]_lUerID_[" + pAlarmer.lUserID + "]" + ".jpg";
                var fs = new FileStream(str, FileMode.Create);
                var iLen = (int)struFaceSnapInfo.dwBackgroundPicLen;
                var by = new byte[iLen];
                Marshal.Copy(struFaceSnapInfo.pBuffer2, by, 0, iLen);
                fs.Write(by, 0, iLen);
                fs.Close();
            }

            //报警时间：年月日时分秒
            var strTimeYear = ((struFaceSnapInfo.dwAbsTime >> 26) + 2000).ToString();
            var strTimeMonth = ((struFaceSnapInfo.dwAbsTime >> 22) & 15).ToString("d2");
            var strTimeDay = ((struFaceSnapInfo.dwAbsTime >> 17) & 31).ToString("d2");
            var strTimeHour = ((struFaceSnapInfo.dwAbsTime >> 12) & 31).ToString("d2");
            var strTimeMinute = ((struFaceSnapInfo.dwAbsTime >> 6) & 63).ToString("d2");
            var strTimeSecond = ((struFaceSnapInfo.dwAbsTime >> 0) & 63).ToString("d2");
            var strTime = strTimeYear + "-" + strTimeMonth + "-" + strTimeDay + " " + strTimeHour + ":" +
                          strTimeMinute + ":" + strTimeSecond;

            var stringAlarm = "人脸抓拍结果，前端设备：" + struFaceSnapInfo.struDevInfo.struDevIP.sIpV4 + "，报警时间：" + strTime;

            ReceiveAlarm?.Invoke(DateTime.Now, strIp, stringAlarm);
        }

        private void ProcessCommAlarm_FaceMatch(ref CameraSdk.NET_DVR_ALARMER pAlarmer, IntPtr pAlarmInfo,
            uint dwBufLen, IntPtr pUser)
        {
            var struFaceMatchAlarm = new CameraSdk.NET_VCA_FACESNAP_MATCH_ALARM();
            var dwSize = (uint)Marshal.SizeOf(struFaceMatchAlarm);
            struFaceMatchAlarm =
                (CameraSdk.NET_VCA_FACESNAP_MATCH_ALARM)Marshal.PtrToStructure(pAlarmInfo,
                    typeof(CameraSdk.NET_VCA_FACESNAP_MATCH_ALARM));

            //报警设备IP地址
            var strIp = pAlarmer.sDeviceIP;

            //保存抓拍人脸子图图片数据
            if (struFaceMatchAlarm.struSnapInfo.dwSnapFacePicLen != 0 &&
                struFaceMatchAlarm.struSnapInfo.pBuffer1 != IntPtr.Zero)
            {
                var str = "Device_FaceMatch_FacePic_[" + strIp + "]_lUerID_[" + pAlarmer.lUserID + "]" + ".jpg";
                var fs = new FileStream(str, FileMode.Create);
                var iLen = (int)struFaceMatchAlarm.struSnapInfo.dwSnapFacePicLen;
                var by = new byte[iLen];
                Marshal.Copy(struFaceMatchAlarm.struSnapInfo.pBuffer1, by, 0, iLen);
                fs.Write(by, 0, iLen);
                fs.Close();
            }

            //保存比对结果人脸库人脸图片数据
            if (struFaceMatchAlarm.struBlackListInfo.dwBlackListPicLen != 0 &&
                struFaceMatchAlarm.struBlackListInfo.pBuffer1 != IntPtr.Zero)
            {
                var str = "Device_FaceMatch_BlackListPic_[" + strIp + "]_lUerID_[" + pAlarmer.lUserID + "]" +
                          "_fSimilarity[" + struFaceMatchAlarm.fSimilarity + "].jpg";
                var fs = new FileStream(str, FileMode.Create);
                var iLen = (int)struFaceMatchAlarm.struBlackListInfo.dwBlackListPicLen;
                var by = new byte[iLen];
                Marshal.Copy(struFaceMatchAlarm.struBlackListInfo.pBuffer1, by, 0, iLen);
                fs.Write(by, 0, iLen);
                fs.Close();
            }

            //抓拍时间：年月日时分秒
            var strTimeYear = ((struFaceMatchAlarm.struSnapInfo.dwAbsTime >> 26) + 2000).ToString();
            var strTimeMonth = ((struFaceMatchAlarm.struSnapInfo.dwAbsTime >> 22) & 15).ToString("d2");
            var strTimeDay = ((struFaceMatchAlarm.struSnapInfo.dwAbsTime >> 17) & 31).ToString("d2");
            var strTimeHour = ((struFaceMatchAlarm.struSnapInfo.dwAbsTime >> 12) & 31).ToString("d2");
            var strTimeMinute = ((struFaceMatchAlarm.struSnapInfo.dwAbsTime >> 6) & 63).ToString("d2");
            var strTimeSecond = ((struFaceMatchAlarm.struSnapInfo.dwAbsTime >> 0) & 63).ToString("d2");
            var strTime = strTimeYear + "-" + strTimeMonth + "-" + strTimeDay + " " + strTimeHour + ":" +
                          strTimeMinute + ":" + strTimeSecond;

            var stringAlarm = "人脸比对报警，抓拍设备：" + struFaceMatchAlarm.struSnapInfo.struDevInfo.struDevIP.sIpV4 + "，抓拍时间："
                              + strTime + "，相似度：" + struFaceMatchAlarm.fSimilarity;

            ReceiveAlarm?.Invoke(DateTime.Now, strIp, stringAlarm);
        }

        private void ProcessCommAlarm_FaceDetect(ref CameraSdk.NET_DVR_ALARMER pAlarmer, IntPtr pAlarmInfo,
            uint dwBufLen, IntPtr pUser)
        {
            //var struFaceDetectInfo =
            //    (CameraSdk.NET_DVR_FACE_DETECTION)Marshal.PtrToStructure(pAlarmInfo,
            //        typeof(CameraSdk.NET_DVR_FACE_DETECTION));

            ////报警设备IP地址
            //var strIp = pAlarmer.sDeviceIP;

            ////报警时间：年月日时分秒
            //var strTimeYear = ((struFaceDetectInfo.dwAbsTime >> 26) + 2000).ToString();
            //var strTimeMonth = ((struFaceDetectInfo.dwAbsTime >> 22) & 15).ToString("d2");
            //var strTimeDay = ((struFaceDetectInfo.dwAbsTime >> 17) & 31).ToString("d2");
            //var strTimeHour = ((struFaceDetectInfo.dwAbsTime >> 12) & 31).ToString("d2");
            //var strTimeMinute = ((struFaceDetectInfo.dwAbsTime >> 6) & 63).ToString("d2");
            //var strTimeSecond = ((struFaceDetectInfo.dwAbsTime >> 0) & 63).ToString("d2");
            //var strTime = strTimeYear + "-" + strTimeMonth + "-" + strTimeDay + " " + strTimeHour + ":" +
            //              strTimeMinute + ":" + strTimeSecond;

            //var stringAlarm = "人脸抓拍结果结果，前端设备：" + struFaceDetectInfo.struDevInfo.struDevIP + "，报警时间：" + strTime;

            //ReceiveAlarm?.Invoke(DateTime.Now, strIp, stringAlarm);
        }

        private void ProcessCommAlarm_CIDAlarm(ref CameraSdk.NET_DVR_ALARMER pAlarmer, IntPtr pAlarmInfo, uint dwBufLen,
            IntPtr pUser)
        {
            //var struCidAlarm = new CameraSdk.NET_DVR_CID_ALARM();
            //var dwSize = (uint)Marshal.SizeOf(struCidAlarm);
            //struCidAlarm =
            //    (CameraSdk.NET_DVR_CID_ALARM)Marshal.PtrToStructure(pAlarmInfo, typeof(CameraSdk.NET_DVR_CID_ALARM));

            ////报警设备IP地址
            //var strIp = pAlarmer.sDeviceIP;

            ////报警时间：年月日时分秒
            //var strTimeYear = struCidAlarm.struTriggerTime.wYear.ToString();
            //var strTimeMonth = struCidAlarm.struTriggerTime.byMonth.ToString("d2");
            //var strTimeDay = struCidAlarm.struTriggerTime.byDay.ToString("d2");
            //var strTimeHour = struCidAlarm.struTriggerTime.byHour.ToString("d2");
            //var strTimeMinute = struCidAlarm.struTriggerTime.byMinute.ToString("d2");
            //var strTimeSecond = struCidAlarm.struTriggerTime.bySecond.ToString("d2");
            //var strTime = strTimeYear + "-" + strTimeMonth + "-" + strTimeDay + " " + strTimeHour + ":" +
            //              strTimeMinute + ":" + strTimeSecond;

            //var stringAlarm = "报警主机CID报告，sCIDCode：" + Encoding.UTF8.GetString(struCidAlarm.sCIDCode).TrimEnd('\0')
            //                  + "，sCIDDescribe：" + Encoding.UTF8.GetString(struCidAlarm.sCIDDescribe).TrimEnd('\0')
            //                  + "，报告类型：" + struCidAlarm.byReportType + "，防区号：" + struCidAlarm.wDefenceNo + "，报警触发时间：" +
            //                  strTime;

            //ReceiveAlarm?.Invoke(DateTime.Now, strIp, stringAlarm);
        }

        private void ProcessCommAlarm_AcsAlarm(ref CameraSdk.NET_DVR_ALARMER pAlarmer, IntPtr pAlarmInfo, uint dwBufLen,
            IntPtr pUser)
        {
            //var struAcsAlarm =
            //    (CameraSdk.NET_DVR_ACS_ALARM_INFO)Marshal.PtrToStructure(pAlarmInfo,
            //        typeof(CameraSdk.NET_DVR_ACS_ALARM_INFO));

            ////报警设备IP地址
            //var strIp = pAlarmer.sDeviceIP;

            ////保存抓拍图片
            //if (struAcsAlarm.dwPicDataLen != 0 && struAcsAlarm.pPicData != IntPtr.Zero)
            //{
            //    var str = "Device_Acs_CapturePic_[" + strIp + "]_lUerID_[" + pAlarmer.lUserID + "]" + ".jpg";
            //    var fs = new FileStream(str, FileMode.Create);
            //    var iLen = (int)struAcsAlarm.dwPicDataLen;
            //    var by = new byte[iLen];
            //    Marshal.Copy(struAcsAlarm.pPicData, by, 0, iLen);
            //    fs.Write(by, 0, iLen);
            //    fs.Close();
            //}

            ////报警时间：年月日时分秒
            //var strTimeYear = struAcsAlarm.struTime.dwYear.ToString();
            //var strTimeMonth = struAcsAlarm.struTime.dwMonth.ToString("d2");
            //var strTimeDay = struAcsAlarm.struTime.dwDay.ToString("d2");
            //var strTimeHour = struAcsAlarm.struTime.dwHour.ToString("d2");
            //var strTimeMinute = struAcsAlarm.struTime.dwMinute.ToString("d2");
            //var strTimeSecond = struAcsAlarm.struTime.dwSecond.ToString("d2");
            //var strTime = strTimeYear + "-" + strTimeMonth + "-" + strTimeDay + " " + strTimeHour + ":" +
            //              strTimeMinute + ":" + strTimeSecond;

            //var stringAlarm = "门禁主机报警信息，dwMajor：" + struAcsAlarm.dwMajor + "，dwMinor：" + struAcsAlarm.dwMinor + "，卡号："
            //                  + Encoding.UTF8.GetString(struAcsAlarm.struAcsEventInfo.byCardNo).TrimEnd('\0') +
            //                  "，读卡器编号：" +
            //                  struAcsAlarm.struAcsEventInfo.dwCardReaderNo + "，报警触发时间：" + strTime;

            //ReceiveAlarm?.Invoke(DateTime.Now, strIp, stringAlarm);
        }

        private void ProcessCommAlarm_IDInfoAlarm(ref CameraSdk.NET_DVR_ALARMER pAlarmer, IntPtr pAlarmInfo,
            uint dwBufLen, IntPtr pUser)
        {
            //var struIdInfoAlarm = new CameraSdk.NET_DVR_ID_CARD_INFO_ALARM();
            //var dwSize = (uint)Marshal.SizeOf(struIdInfoAlarm);
            //struIdInfoAlarm =
            //    (CameraSdk.NET_DVR_ID_CARD_INFO_ALARM)Marshal.PtrToStructure(pAlarmInfo,
            //        typeof(CameraSdk.NET_DVR_ID_CARD_INFO_ALARM));

            ////报警设备IP地址
            //var strIp = pAlarmer.sDeviceIP;

            ////保存抓拍图片
            //if (struIdInfoAlarm.dwCapturePicDataLen != 0 && struIdInfoAlarm.pCapturePicData != IntPtr.Zero)
            //{
            //    var str = "Device_ID_CapturePic_[" + strIp + "]_lUerID_[" + pAlarmer.lUserID + "]" + ".jpg";
            //    var fs = new FileStream(str, FileMode.Create);
            //    var iLen = (int)struIdInfoAlarm.dwCapturePicDataLen;
            //    var by = new byte[iLen];
            //    Marshal.Copy(struIdInfoAlarm.pCapturePicData, by, 0, iLen);
            //    fs.Write(by, 0, iLen);
            //    fs.Close();
            //}

            ////保存身份证图片数据
            //if (struIdInfoAlarm.dwPicDataLen != 0 && struIdInfoAlarm.pPicData != IntPtr.Zero)
            //{
            //    var str = "Device_ID_IDPic_[" + strIp + "]_lUerID_[" + pAlarmer.lUserID + "]" + ".jpg";
            //    var fs = new FileStream(str, FileMode.Create);
            //    var iLen = (int)struIdInfoAlarm.dwPicDataLen;
            //    var by = new byte[iLen];
            //    Marshal.Copy(struIdInfoAlarm.pPicData, by, 0, iLen);
            //    fs.Write(by, 0, iLen);
            //    fs.Close();
            //}

            ////保存指纹数据
            //if (struIdInfoAlarm.dwFingerPrintDataLen != 0 && struIdInfoAlarm.pFingerPrintData != IntPtr.Zero)
            //{
            //    var str = "Device_ID_FingerPrint_[" + strIp + "]_lUerID_[" + pAlarmer.lUserID + "]" + ".data";
            //    var fs = new FileStream(str, FileMode.Create);
            //    var iLen = (int)struIdInfoAlarm.dwFingerPrintDataLen;
            //    var by = new byte[iLen];
            //    Marshal.Copy(struIdInfoAlarm.pFingerPrintData, by, 0, iLen);
            //    fs.Write(by, 0, iLen);
            //    fs.Close();
            //}

            ////报警时间：年月日时分秒
            //var strTimeYear = struIdInfoAlarm.struSwipeTime.wYear.ToString();
            //var strTimeMonth = struIdInfoAlarm.struSwipeTime.byMonth.ToString("d2");
            //var strTimeDay = struIdInfoAlarm.struSwipeTime.byDay.ToString("d2");
            //var strTimeHour = struIdInfoAlarm.struSwipeTime.byHour.ToString("d2");
            //var strTimeMinute = struIdInfoAlarm.struSwipeTime.byMinute.ToString("d2");
            //var strTimeSecond = struIdInfoAlarm.struSwipeTime.bySecond.ToString("d2");
            //var strTime = strTimeYear + "-" + strTimeMonth + "-" + strTimeDay + " " + strTimeHour + ":" +
            //              strTimeMinute + ":" + strTimeSecond;

            //var stringAlarm = "身份证刷卡信息，dwMajor：" + struIdInfoAlarm.dwMajor + "，dwMinor：" + struIdInfoAlarm.dwMinor
            //                  + "，身份证号：" +
            //                  Encoding.UTF8.GetString(struIdInfoAlarm.struIDCardCfg.byIDNum).TrimEnd('\0') +
            //                  "，姓名：" + Encoding.UTF8.GetString(struIdInfoAlarm.struIDCardCfg.byName).TrimEnd('\0') +
            //                  "，刷卡时间：" + strTime;

            //ReceiveAlarm?.Invoke(DateTime.Now, strIp, stringAlarm);
        }

        private bool AutoLogin(string cameraIp, int cameraPort, string userName, string password, out int userId)
        {
            userId = -1;

            var dvrIpAddress = cameraIp; //设备IP地址或者域名 Device IP
            var dvrPortNumber = cameraPort;//设备服务端口号 Device Port
            var dvrUserName = userName;//设备登录用户名 User name to login
            var dvrPassword = password;//设备登录密码 Password to login

            if (dvrIpAddress == "" || dvrPortNumber == 0 ||
                dvrUserName == "" || dvrPassword == "")
            {
                Common.Log4.LogManage.WriteErr(@"Please input IP, Port, User name and Password!");
                return false;
            }

            if (iDeviceNumber >= 20)
            {
                Common.Log4.LogManage.WriteErr(@"本程序限制最多添加20台设备！");
                return false;
            }

            var deviceInfo = new CameraSdk.NET_DVR_DEVICEINFO_V30();

            //登录设备 Login the device
            userId = CameraSdk.NET_DVR_Login_V30(dvrIpAddress, dvrPortNumber, dvrUserName, dvrPassword, ref deviceInfo);
            if (userId < 0)
            {
                var lastErr = CameraSdk.NET_DVR_GetLastError();
                var strErr = "NET_DVR_Login_V30 failed, error code= " + lastErr; //登录失败，输出错误号 Failed to login and output the error code
                Common.Log4.LogManage.WriteErr(strErr);
                return false;
            }
            else
            {
                //登录成功
                iDeviceNumber++;
                return true;
            }
        }

        private bool LoginOut()
        {
            if (!CameraSdk.NET_DVR_Logout(_mUserId))
            {
                var lastErr = CameraSdk.NET_DVR_GetLastError();
                var strErr = "NET_DVR_Logout failed, error code=" + lastErr; 
                Common.Log4.LogManage.WriteErr(strErr);
                return false;
            }
            UserId = -1;
            return true;
        }

        private bool SetAlarm(int userId)
        {
            var struAlarmParam = new CameraSdk.NET_DVR_SETUPALARM_PARAM();
            struAlarmParam.dwSize = (uint)Marshal.SizeOf(struAlarmParam);
            struAlarmParam.byLevel = 1; //0- 一级布防,1- 二级布防
            struAlarmParam.byAlarmInfoType = 1;//智能交通设备有效，新报警信息类型

            m_lAlarmHandle[userId] = CameraSdk.NET_DVR_SetupAlarmChan_V41(userId, ref struAlarmParam);
            if (m_lAlarmHandle[userId] < 0)
            {
                var lastErr = CameraSdk.NET_DVR_GetLastError();
                var strErr = "布防失败，错误号：" + lastErr; //布防失败，输出错误号
                Common.Log4.LogManage.WriteErr(strErr);
                return false;
            }
            else
            {
                Common.Log4.LogManage.WriteInfo(@"布防成功");
                return true;
            }
        }

        private bool StartListen(string localIp, int localPort)
        {
            string sLocalIp = localIp;
            ushort wLocalPort = (ushort)localPort;

            if (m_falarmData == null)
            {
                m_falarmData = MsgCallback;
            }

            iListenHandle = CameraSdk.NET_DVR_StartListen_V30(sLocalIp, wLocalPort, m_falarmData, IntPtr.Zero);
            if (iListenHandle < 0)
            {
                var lastErr = CameraSdk.NET_DVR_GetLastError();
                var strErr = "启动监听失败，错误号：" + lastErr; //启动监听失败，输出错误号
                Common.Log4.LogManage.WriteErr(strErr);
                return false;
            }
            else
            {
                Common.Log4.LogManage.WriteInfo("成功启动监听！");
                return true;
            }
        }
    }

    public class CameraSetup
    {
        public string CameraIp { get; set; }
        public int CameraPort { get; set; }
        public string UserName { get; set; }
        public string Password { get; set; }
        /// <summary>
        /// 1:识别车牌；2:监控
        /// </summary>
        private int _cameraType = 1;
        public int CameraType
        {
            get { return _cameraType; }
            set { _cameraType = value; }
        }
        /// <summary>
        /// 1:直接预览；2:回调解码
        /// </summary>
        private int _previewMode = 1;
        public int PreviewMode
        {
            get { return _previewMode; }
            set { _previewMode = value; }
        }
        private string _localIp = "127.0.0.1";
        public string LocalIp
        {
            get { return _localIp; }
            set { _localIp = value; }
        }
        private int _localPort = 7200;
        public int LocalPort
        {
            get { return _localPort; }
            set { _localPort = value; }
        }
    }
}
